package se.webbzon.oschi01.item;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import se.webbzon.oschi01.json.JsonArray;
import se.webbzon.oschi01.json.JsonInputStreamReader;
import se.webbzon.oschi01.json.JsonNumber;
import se.webbzon.oschi01.json.JsonObject;
import se.webbzon.oschi01.json.JsonString;
import se.webbzon.oschi01.json.JsonType;

public class TranslationJsonReader implements TranslationReader {
	
	@SuppressWarnings("resource")
	@Override public Map<ItemEntry, ItemEntry> read(InputStream source) throws IOException {
		Map<ItemEntry, ItemEntry> map = new HashMap<ItemEntry,ItemEntry>();
		JsonInputStreamReader reader = new JsonInputStreamReader(source);
		JsonString key = new JsonString();
		JsonType root = reader.read();
		if (root instanceof JsonArray) {
			JsonArray array = (JsonArray) root;
			for (JsonType child : array) {
				if (child instanceof JsonObject) {
					JsonObject entry = (JsonObject) child;
					key.setValue("from");
					JsonType from = entry.get(key);
					if (from instanceof JsonObject) {
						ItemEntry lhs = toEntry((JsonObject) from, key);
						key.setValue("to");
						JsonType to = entry.get(key);
						if (to instanceof JsonObject) {
							ItemEntry rhs = toEntry((JsonObject) to, key);
							map.put(lhs, rhs);
						} else 
							throw new IOException("Unable to interpret JSON structure. Item entry must be a JSON object.");
					} else
						throw new IOException("Unable to interpret JSON structure. Item entry must be a JSON object." + entry);
				} else
					throw new IOException("Unable to interpret JSON structure. Mapping must be a JSON object.");
			}
		} else
			throw new IOException("Unable to interpret JSON structure. Structure root must be a JSON array.");
		return map;
	}
	
	private static final ItemEntry toEntry(JsonObject obj, JsonString key) throws IOException {
		key.setValue("id");
		JsonType jsonId = obj.get(key);
		key.setValue("type");
		JsonType jsonType = obj.get(key);
		key.setValue("mod");
		JsonType jsonMod = obj.get(key);
		key.setValue("name");
		JsonType jsonName = obj.get(key);
		key.setValue("class");
		JsonType jsonClazz = obj.get(key);
		if (jsonId instanceof JsonNumber) {
			int id = (int) (double) ((JsonNumber) jsonId).getValue();
			if (jsonType instanceof JsonNumber) {
				int type = (int) (double) ((JsonNumber) jsonType).getValue();
				if (jsonMod instanceof JsonString) {
					String mod = ((JsonString) jsonMod).getValue();
					if (jsonName instanceof JsonString) {
						String name = ((JsonString) jsonName).getValue();
						if (jsonClazz instanceof JsonString) {
							String clazz = ((JsonString) jsonClazz).getValue();
							try {
								ItemType itemType = ItemType.values()[type];
								return new DefaultItemEntry(id, itemType, mod, name, clazz);
							} catch (ArrayIndexOutOfBoundsException e) {
								throw new IOException("Invalid value in JSON structure (type).");
							}
						} else
							throw new IOException("Missing or invalid value in JSON structure (class).");
					} else
						throw new IOException("Missing or invalid value in JSON structure (name).");
				} else
					throw new IOException("Missing or invalid value in JSON structure (mod).");
			} else
				throw new IOException("Missing or invalid value in JSON structure (type).");
		} else
			throw new IOException("Missing or invalid value in JSON structure (id).");
	}

}
